package controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import persistence.MaterialMapper;
import view.ListaMaterialesPanel;
import view.MaterialPanel;
import model.Material;
import model.Proveedor;

public class MaterialController {
	private List<Material> materiales;
	private MainController mainController;
	private static MaterialController instance;
	private MaterialPanel materialPanel;
	
	/** variable para controlar si la collection en memoria equivale a la tabla de materiales */
	private boolean fullyLoaded = false;
	
	private MaterialController() {
		materiales = new ArrayList<Material>();
		mainController = MainController.getInstance();
	}
	
	public static MaterialController getInstance() {
		if(instance == null) {
			instance = new MaterialController();
		}
		
		return instance;
	}
	
	/**
	 * Alta de un nuevo material. El codigo es unico, por lo tanto no debe existir ya un material con el mismo codigo. De no existir el proveedor con el codigo
	 * recibido, no se efectua el alta del material.
	 * @param codigo codigo unico del material a agregar
	 * @param nombre nombre del material
	 * @param stock stock del material
	 * @param ptoPedido punto de pedido
	 * @param codigoProveedor codigo del proveedor que provee dicho material
	 * @param precio precio del material
	 * @return <b>true</b> si se agrega el material correctamente, <b>false</b> si no se pudo agregar el material
	 */
	public boolean altaMaterial(String codigo, String nombre, int stock, int ptoPedido, Proveedor proveedor, float precio){
		boolean result = false;
		if (buscarMaterial(codigo) == null){
				Material nuevoMaterial;
				nuevoMaterial = new Material(codigo, nombre, stock, ptoPedido, proveedor, precio);
				result = nuevoMaterial.guardar();
				materiales.add(nuevoMaterial);
				proveedor.agregarMaterial(nuevoMaterial);
				
		}
		return result;
	}
	
	/**
	 * Busqueda del material con el codigo recibido.
	 * @param codigo codigo del material a buscar
	 * @return <b>null</b> en caso de que no exista un material con el codigo recibido, el Material correspondiente al codigo buscado
	 */
	public Material buscarMaterial(String codigo){
		Material result = null;
		
		for(Material material: getMateriales()) {
			if(material.hasCodigo(codigo)) {
				result = material;
				break;
			}
		}
		
		return result;
	}
	
	public boolean bajaMaterial(String codigo) {
		boolean result = false;
		Material material = buscarMaterial(codigo);
		if(material != null) {
			result = material.eliminar();
			materiales.remove(material);
		}
		return result;
	}

	/**
	 * Metodo que retorna todos los materiales existentes
	 * @return List<Material> materiales
	 */
	public List<Material> getMateriales() {
		if (!fullyLoaded) {
			materiales = MaterialMapper.getInstance().buscarTodos();
			fullyLoaded = true;
		}
			
		return materiales;
	}
	
	public void altaMaterialPanel() {
		Vector<Proveedor> proveedores = new Vector<Proveedor>(mainController.getProveedores());
		materialPanel = new MaterialPanel(proveedores);
		materialPanel.showPanel();
	}

	public boolean mostrarMaterial(String codigo) {
		boolean result = false;
		Material material = buscarMaterial(codigo);
		
		if(material != null) {
			result = true;
			Vector<Proveedor> proveedores = new Vector<Proveedor>(mainController.getProveedores());
			materialPanel = new MaterialPanel(proveedores, material);
			materialPanel.showPanel();
		}
		
		return result;
	}

	public boolean modificarMaterial(String codigo, String nuevoCodigo, String nombre, int cantidadStock, int puntoDePedido, Proveedor proveedor, float costo) {
		boolean result = false;
		Material modificado = buscarMaterial(codigo);
		if(modificado != null) {
			modificado.setCodigo(nuevoCodigo);
			modificado.setNombre(nombre);
			modificado.setCantidadStock(cantidadStock);
			modificado.setPuntoDePedido(puntoDePedido);
			modificado.setProveedor(proveedor);
			modificado.setCosto(costo);
			result = modificado.modificar();
		}
		return result;
	}

	public void mostrarMateriales() {
		ListaMaterialesPanel materialesPanel = new ListaMaterialesPanel(getMateriales());
		materialesPanel.showPanel();
	}
}
